import VPager from "./index.vue";
import VInput from "@/components/input/input.vue";
import "./index.less";
export default {
	name: "VPagination",
	props: {
		background: Boolean,
		pageSize: {
			//每页显示条目数量（暂不支持，等pageSizes属性完成后再使用）
			type: Number,
			default: 10,
		},
		total: Number, //总条目数
		pageCount: Number, //总页数
		pagerCount: {
			//页码按钮的数量，当总页数超过该值时会折叠。大于等于 5 且小于等于 21 的奇数
			type: Number,
			default: 7,
		},
		currentPage: {
			type: Number,
			default: 1,
		},
		layout: {
			//组件布局，子组件名用逗号分隔。目前有：prev, pager, next, jumper, total, slot
			default: "total,prev, pager, next, jumper, slot",
		},
		pageSizes: {
			type: Array,
			default() {
				return [10, 20, 30, 40, 50, 100];
			},
		}, //每页显示个数选择器的选项设置（暂时不支持，select组件还不太好，下次记得加上）
		popperClass: String,
		prevText: String, //上一页文本
		nextText: String, //下一页文本
		disabled: Boolean,
		hideOnSinglePage: Boolean, //只有一页时是否隐藏
	},
	data() {
		return {
			internalCurrentPage: 1,
			internalPageSize: 0,
			lastEmittedPage: -1,
			userChangePageSize: false,
		};
	},
	computed: {
		internalPageCount() {
			if (typeof this.total === "number") {
				return Math.max(1, Math.ceil(this.total / this.internalPageSize));
			} else if (typeof this.pageCount === "number") {
				return Math.max(1, this.pageCount);
			}
			return null;
		},
	},
	watch: {
		currentPage: {
			immediate: true,
			handler(val) {
				this.internalCurrentPage = this.getValidCurrentPage(val);
			},
		},
		pageSize: {
			immediate: true,
			handler(val) {
				this.internalPageSize = isNaN(val) ? 10 : val;
			},
		},
		internalCurrentPage: {
			immediate: true,
			handler(newVal) {
				this.$emit("update:currentPage", newVal);
				this.lastEmittedPage = -1;
			},
		},
	},
	render() {
		const layout = this.layout;
		if (!layout) return null;

		if (
			this.hideOnSinglePage &&
			(!this.internalPageCount || this.internalPageCount === 1)
		)
			return null;

		let template = (
			<div
				class={[
					"v-pagination",
					{
						"is-background": this.background,
					},
				]}
			></div>
		);
		const TEMPLATE_MAP = {
			prev: <prev></prev>,
			jumper: <jumper></jumper>,
			pager: (
				<v-pager
					pageCount={this.pageCount}
					currentPage={this.currentPage}
					pagerCount={this.pagerCount}
					on-change={this.onChange}
					disabled={this.disabled}
				></v-pager>
			),
			next: <next></next>,
			slot: <slot>{this.$slots.default ? this.$slots.default : ""}</slot>,
			total: <total></total>,
		};
		const components = layout.split(",").map((item) => item.trim());

		template.children = template.children || [];

		components.forEach((compo) => {
			template.children.push(TEMPLATE_MAP[compo]);
		});

		return template;
	},
	components: {
		VPager,
		Prev: {
			render() {
				return (
					<button
						type="button"
						class="prev-btn"
						disabled={
							this.$parent.disabled || this.$parent.internalCurrentPage <= 1
						}
						on-click={this.$parent.prev}
					>
						{this.$parent.prevText ? (
							<span>{this.$parent.prevText}</span>
						) : (
							<i class="v-arrow-left-icon">&lt;</i>
						)}
					</button>
				);
			},
		},
		Next: {
			render() {
				return (
					<button
						type="button"
						class="next-btn"
						disabled={
							this.$parent.disabled ||
							this.$parent.internalCurrentPage ===
								this.$parent.internalPageCount ||
							this.$parent.internalPageCount === 0
						}
						on-click={this.$parent.next}
					>
						{this.$parent.nextText ? (
							<span>{this.$parent.nextText}</span>
						) : (
							<i class="v-arrow-right-icon">&gt;</i>
						)}
					</button>
				);
			},
		},
		Jumper: {
			components: { VInput },
			data() {
				return {
					userInput: null,
				};
			},
			watch: {
				"$parent.internalCurrentPage"() {
					this.userInput = null;
				},
			},
			methods: {
				handleKeyup({ keyCode, target }) {
					// Chrome, Safari, Firefox triggers change event on Enter
					// Hack for IE: https://github.com/ElemeFE/element/issues/11710
					// Drop this method when we no longer supports IE
					if (keyCode === 13) {
						this.handleChange(target.value);
					}
				},
				handleInput(value) {
					this.userInput = value;
				},
				handleChange(value) {
					this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(
						value
					);
					this.$parent.emitChange();
					this.userInput = null;
				},
			},
			render() {
				return (
					<span class="v-pagination__jump">
						前往
						<v-input
							class={"v-pagination__inp"}
							min={1}
							max={this.$parent.internalPageCount}
							value={
								this.userInput !== null
									? this.userInput
									: this.$parent.internalCurrentPage
							}
							type="number"
							disabled={this.$parent.disabled}
							nativeOnKeyup={this.handleKeyup}
							onInput={this.handleInput}
							onChange={this.handleChange}
						/>
						页
					</span>
				);
			},
		},
		Total: {
			render() {
				return typeof this.$parent.total === "number" ? (
					<span class="v-pagination__total">共{this.$parent.total}条记录</span>
				) : (
					""
				);
			},
		},
	},
	methods: {
		onChange(e) {
			this.$emit("update:currentPage", e);
			this.$emit("current-change", e);
		},

		valueEquals(a, b) {
			if (a === b) return true;
			if (!(a instanceof Array)) return false;
			if (!(b instanceof Array)) return false;
			if (a.length !== b.length) return false;
			for (let i = 0; i !== a.length; ++i) {
				if (a[i] !== b[i]) return false;
			}
			return true;
		},

		prev() {
			if (this.disabled) return;
			const newVal = this.internalCurrentPage - 1;
			this.internalCurrentPage = this.getValidCurrentPage(newVal);
			this.$emit("prev-click", this.internalCurrentPage);
			this.emitChange();
		},

		next() {
			if (this.disabled) return;
			const newVal = this.internalCurrentPage + 1;
			this.internalCurrentPage = this.getValidCurrentPage(newVal);
			this.$emit("next-click", this.internalCurrentPage);
			this.emitChange();
		},

		//获取有效的当前页
		getValidCurrentPage(value) {
			value = parseInt(value, 10);

			const havePageCount = typeof this.internalPageCount === "number";

			let resetValue;
			if (!havePageCount) {
				if (isNaN(value) || value < 1) resetValue = 1;
			} else {
				if (value < 1) {
					resetValue = 1;
				} else if (value > this.internalPageCount) {
					resetValue = this.internalPageCount;
				}
			}

			if (resetValue === undefined && isNaN(value)) {
				resetValue = 1;
			} else if (resetValue === 0) {
				resetValue = 1;
			}

			return resetValue === undefined ? value : resetValue;
		},

		emitChange() {
			this.$nextTick(() => {
				if (
					this.internalCurrentPage !== this.lastEmittedPage ||
					this.userChangePageSize
				) {
					this.$emit("current-change", this.internalCurrentPage);
					this.lastEmittedPage = this.internalCurrentPage;
					this.userChangePageSize = false;
				}
			});
		},
	},
};
